package com.grupoconstruobras.sigo.general.util;

import com.grupoconstruobras.sigo.ServiceException;
import com.grupoconstruobras.sigo.general.enums.SiNo;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.logging.Logger;

import javax.persistence.Query;

import org.apache.commons.beanutils.BeanUtils;


//FIXME: import org.jboss.solder.el.Expressions;

public abstract class GenericJPAManager<T, PK extends Serializable> extends JpaManager implements
    IGenericJPAManager<T, PK> {

  protected Class<T> entityClass;

  protected Logger logger = Logger.getLogger("SIJYP");

  @SuppressWarnings("unchecked")
  public GenericJPAManager() {
    this.entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
  }

  @Override
  public T selectById(PK id) {
    if (id != null) {
      T t = entityManager.find(entityClass, id);
      return t;
    }
    return null;
  }

  @Override
  //@UsuarioLogger
  public T create(T t) {
    entityManager.persist(t);
    return t;
  }

  @Override
  //@UsuarioLogger
  public T update(T t) {
    return entityManager.merge(t);
  }

  @Override
  public void delete(T t) {
    t = entityManager.merge(t);
    entityManager.remove(t);
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<T> findAll() {
    String stringQuery = "SELECT o FROM " + this.entityClass.getSimpleName() + " o";
    List<T> listT = entityManager.createQuery(stringQuery).getResultList();
    return listT;
  }

  @Override
  public void deleteById(PK id) {
    T t = this.selectById(id);
    t = entityManager.merge(t);
    entityManager.remove(t);
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<T> findAllActives() {
    String stringQuery = "SELECT o FROM " + this.entityClass.getSimpleName()
                         + " o where o.activo = '" + SiNo.SI.toString() + "'";
    Query query = entityManager.createQuery(stringQuery);
    query.setHint("org.hibernate.cacheable", Boolean.TRUE);
    List<T> listT = query.getResultList();
    return listT;
  }

  protected T logicMerge(PK id, T entity) throws ServiceException {
	  T persist = selectById(id);
    try {
      BeanUtils.copyProperties(persist, entity);
    } catch (IllegalAccessException | InvocationTargetException e) {
      throw new ServiceException(e.getMessage(), e);
    }
    return persist;
  }
  
}
